﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using RestUpMVC.Resource;
using RestUpMVC.Test.ExternalResources;
using RestUpMVC.Test.TestClasses;

namespace RestUpMVC.Test.Resource
{
    [TestClass]
    public class ResourceControllerResolverTest
    {
        [TestMethod]
        public void ResolveMetaData_ShouldResolveTheControllerForTheGivenResource()
        {
            var resourceControllerResolver = new ResourceControllerResolver();
            var metaData = new ResourceMetaData();
            resourceControllerResolver.ResolveMetaData(typeof(TestResource), metaData);

            Assert.AreSame(typeof(TestResourceController), metaData.ControllerType);
        }
        
        [TestMethod]
        public void ResolveMetaData_ShouldResolveTheControllerForAResourceInASeparateAssembly()
        {
            var resourceControllerResolver = new ResourceControllerResolver();
            var metaData = new ResourceMetaData();
            resourceControllerResolver.ResolveMetaData(typeof(ExternalResource), metaData);

            Assert.AreSame(typeof(ExternalResourceController), metaData.ControllerType);
        }

        [TestMethod]
        [ExpectedException(typeof(ResourceControllerNotFoundException))]
        public void ResolveMetaData_ShouldThrowAnExcpetionIfNoControllerExistsForTheResource()
        {
            var resourceControllerResolver = new ResourceControllerResolver();
            var metaData = new ResourceMetaData();
            //pass in an anon type since there is no controller class that will match the convention of {typename}Controller
            resourceControllerResolver.ResolveMetaData(new {foo="bar"}.GetType(), metaData);
        }

        [TestMethod]
        public void ResolveMetaData_ShouldDetermineIfTheListOperationIsAvailableForAResource()
        {
            var resourceControllerResolver = new ResourceControllerResolver();
            var metaData = new ResourceMetaData();

            resourceControllerResolver.ResolveMetaData(typeof(TestResource), metaData);

            Assert.IsTrue(metaData.AllowList);
        }

        [TestMethod]
        public void ResolveMetaData_ShouldDetermineIfTheGetOperationIsAvailableForAResource()
        {
            var resourceControllerResolver = new ResourceControllerResolver();
            var metaData = new ResourceMetaData();

            resourceControllerResolver.ResolveMetaData(typeof(TestResource), metaData);

            Assert.IsTrue(metaData.AllowGet);
        }

        [TestMethod]
        public void ResolveMetaData_ShouldDetermineIfThePutOperationIsAvailableForAResource()
        {
            var resourceControllerResolver = new ResourceControllerResolver();
            var metaData = new ResourceMetaData();

            resourceControllerResolver.ResolveMetaData(typeof(TestResource), metaData);

            Assert.IsTrue(metaData.AllowPut);
        }

        [TestMethod]
        public void ResolveMetaData_ShouldDetermineIfThePostOperationIsAvailableForAResource()
        {
            var resourceControllerResolver = new ResourceControllerResolver();
            var metaData = new ResourceMetaData();

            resourceControllerResolver.ResolveMetaData(typeof(TestResource), metaData);

            Assert.IsTrue(metaData.AllowPost);
        }

        [TestMethod]
        public void ResolveMetaData_ShouldDetermineIfTheDeleteOperationIsAvailableForAResource()
        {
            var resourceControllerResolver = new ResourceControllerResolver();
            var metaData = new ResourceMetaData();

            resourceControllerResolver.ResolveMetaData(typeof(TestResource), metaData);

            Assert.IsTrue(metaData.AllowDelete);
        }
    }
}